import Circle, { ICircle } from "../base/Circle";
import Config from "../config/Config";
import Snake from "./Snake";
import Chunk from "../world/Chunk";
import World from "../world/World";

const cfg = Config.snake

/** 蛇节点类 */
export default class SnakeNode extends Circle {

    /** 对象池 */
    static pool: SnakeNode[] = []

    /** 标识 */
    protected _id: number
    /** 节点主人 */
    protected _owner: Snake
    /** 当前索引 */
    protected _idx: number
    /** 当前节点间隔 */
    protected _spacing: number
    /** 所在区块 */
    protected _chunks: Chunk[]
    /** 所在世界 */
    protected _world: World
    /** 是否存在 */
    protected _isLive: Boolean

    /** 必须通过create创建蛇节点 */
    protected constructor() { super() }

    /** 通过对象池创建蛇节点 */
    static create(obj: SnakeNode) {
        let ins = SnakeNode.pool.pop() || new SnakeNode()
        ins.set(obj)
        ins._isLive = true
        ins._world = obj._world
        ins._id = obj._world.getNewSnakeNodeId()
        ins._idx = obj._idx + 1;
        ins._owner = obj.owner;
        //设置保存点
        ins._owner.head.savePath.push(ins.cp())
        ins.updateChunks()
        return ins
    }

    /** 回收到对象池中 */
    recy() {
        //放入对象池
        SnakeNode.pool.push(this)
    }

    /** 从世界中销毁 */
    destory() {
        //从区块的中移除
        this._chunks.forEach(chunk => chunk.removeSnakeNode(this))
        this._chunks = null
        this._world = null
        this._owner = null
        this._isLive = false
        this.recy()
    }

    /** 每帧执行 */
    update() {
        this.moving()
        this.updateChunks()
    }


    /** 获取蛇节点之间的间隔 */
    getSpacing() {
        return this.w * cfg.initSpacing - Math.pow(this.w - cfg.initWidth, 0.88);
    }

    /** 设置宽度 */
    setWidth(w: number = this.w) {
        this.w = w
        this._spacing = this.getSpacing()
    }

    /** 更新所在区块 */
    updateChunks() {
        if (!this._chunks) {
            //加入到区块
            this._chunks = this._world.getChunks(this)
            this._chunks.forEach(chunk => chunk.addSnakeNode(this))
        } else {
            let update = false
            for (let i = this._chunks.length - 1; i >= 0; i--) {
                //如果不在区块
                if (!this.collide(this._chunks[i])) {
                    //从区块中删除
                    let chunk = this._chunks.splice(i, 1)[0]
                    chunk.removeSnakeNode(this)
                    this.onExitChunk(chunk)
                    //启动更新
                    update = true
                }
            }
            if (update) {
                this._world.getChunks(this).forEach(chunk => {
                    //如果当前区块中没有
                    if (this._chunks.indexOf(chunk) == -1) {
                        //加入到区块中
                        chunk.addSnakeNode(this)
                        this._chunks.push(chunk)
                        this.onJoinChunk(chunk)
                    }
                })
            }
        }
    }

    /** 进入区块(给head用) */
    protected onJoinChunk(chunk: Chunk) { }
    /** 离开区块(给head用) */
    protected onExitChunk(chunk: Chunk) { }

    /** 移动 */
    protected moving() {
        let head = this._owner.head
        let savePos = head.savePath[this._idx]
        this.set(savePos).moveForward(head.saveDis)
    }

    // ================================================================

    /** 唯一标识 */
    get id() { return this._id }

    /** 节点主人 */
    get owner() { return this._owner }

    /** 节点索引 */
    get idx() { return this._idx }
}